#include "AppMenuItem.h"
#include "AppMenuPanel.h"
#include "../CMD/CmdMgr.h"
#include <core/ImageMgr.h>
#include <widgets/SImageButton.h>
#include <QJsonObject>
#include <QBoxLayout>
#include <QLabel>
#include <QMouseEvent>
#include <QStylePainter>
#include <QPushButton>
#include <QTimer>

//QT在重新排版时，会导致onhover判断出现一些问题，应该想办法避免relayout时，已有控件的位置变动
bool AppMenuItem::s_notifying = false;

AppMenuItem::AppMenuItem(QJsonObject* obj, QWidget* parent)
	:QWidget(parent)
{
	construct(obj);
	setMouseTracking(true);
}

AppMenuItem::AppMenuItem(int cmdId, QWidget* parent)
	:QWidget(parent)
{
	construct(cmdId);
	setMouseTracking(true);
}


bool AppMenuItem::isRedPoint()
{
	Command* cmd = CmdMgr::instance().command(m_item.cmdId);
	if (cmd)
	{
		return cmd->isRedPoint();
	}
	return false;
}


bool AppMenuItem::isEnabled()
{
	Command* cmd = CmdMgr::instance().command(m_item.cmdId);
	return cmd && !cmd->module().isEmpty();
}

void AppMenuItem::leaveEvent(QEvent* event)
{
	if (s_notifying)//during relayout!!!
		return;
	m_hover = false;
	onHoverChanged();
}

void AppMenuItem::mouseMoveEvent(QMouseEvent* e)
{
	if (s_notifying)
		return;
	QRect hoverRect = rect();
	hoverRect.adjust(0, 6, 0, -6);
	bool hover = hoverRect.contains(e->pos());
	if (hover != m_hover)
	{
		m_hover = hover;
		onHoverChanged();
	}
}

void AppMenuItem::mouseReleaseEvent(QMouseEvent* e)
{
	QRect hoverRect = rect();
	hoverRect.adjust(0, 6, 0, -6);
	bool clicked = hoverRect.contains(e->pos());
	if (clicked)
	{
		m_hover = false;
		onHoverChanged();
		AppMenuPanel::g_menuPanel()->hide();
		QTimer::singleShot(0, [this]() { CmdMgr::instance().execCmd(m_item.cmdId); });
	}
}

void AppMenuItem::paintEvent(QPaintEvent* event)
{
	QStylePainter painter(this);

	painter.setPen(Qt::transparent);
	painter.setRenderHint(QPainter::Antialiasing);//抗锯齿

	if (m_hover && isEnabled())
	{
		QRect hoverRect = rect();
		hoverRect.adjust(0, 6, 0, -6);
		//painter.fillRect(hoverRect, QColor(26, 79, 71));
		painter.setBrush(QBrush(QColor(26, 79, 71)));
		painter.drawRoundedRect(hoverRect, 2, 2);
	}
	else if (!isEnabled())
	{
		QRect hoverRect = rect();
		hoverRect.adjust(0, 6, 0, -6);
		//painter.fillRect(hoverRect, Qt::gray);
		painter.setBrush(QBrush(Qt::gray));
		painter.drawRoundedRect(hoverRect, 2, 2);
	}

	if (m_item.tag != Command::CmdTag::kNone)
	{
		SImage* image = ImgMgr::instance().image(m_item.tag == Command::CmdTag::kHot ? "guiframe_catalogue_hot" : "guiframe_catalogue_new",WidgetStatus::kNormal, devicePixelRatioF());
		if (image)
		{
			QRect titleFrame = m_labelTitle->frameGeometry();
			int posX = titleFrame.right() - 5;
			
			painter.setRenderHint(QPainter::SmoothPixmapTransform);//处理图片失真
			painter.drawImage(posX, 0, *image);
		}
	}
}

void AppMenuItem::construct(int cmdId)
{
	m_item.tag = Command::CmdTag::kNone;
	m_item.cmdId = cmdId;;
	Command* cmd = CmdMgr::instance().command(m_item.cmdId);
	if (cmd)
	{
		m_item.tag = cmd->tag();
		m_item.abbr = cmd->abbr();
		m_item.title = cmd->name();
	}
	else
	{
		Q_ASSERT_X(false, "Command can't be found!", QString::number(cmdId).toStdString().c_str());
		return;
	}

	setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
	setFixedSize(146, 42);
	m_layout = new QHBoxLayout();
	m_layout->setContentsMargins(5, 0, 1, 0);
	m_layout->setSpacing(0);

	QString title = "<p style=\"font-size:12px; color:#FFEBC8\">%1</p>";
	title = title.arg(m_item.title);
	m_labelTitle = new QLabel(title);
	//so I can get the mousemove event when mouse is move to it very quickly!
	m_labelTitle->setAttribute(Qt::WA_TransparentForMouseEvents);
	m_layout->addWidget(m_labelTitle);

	m_layout->addStretch();

	QString abbr = "<p style=\"font-size:12px; color:#458C81\">%1</p>";
	abbr = abbr.arg(m_item.abbr);
	m_labelAbbr = new QLabel(abbr);
	m_labelAbbr->setAttribute(Qt::WA_TransparentForMouseEvents);
	m_layout->addWidget(m_labelAbbr);

	//TODO: check if can add 
	m_btn = new SImageButton(this, "guiframe_catalogue_add");
	m_btn->setVisible(false);
	m_btn->setFixedSize(24, 24);
	connect(m_btn, &SImageButton::clicked, this, &AppMenuItem::onBtnClicked);

	m_layout->addWidget(m_btn);

	m_spacer = new QSpacerItem(8, 2, QSizePolicy::Fixed, QSizePolicy::Preferred);

	setLayout(m_layout);
}

void AppMenuItem::construct(QJsonObject* obj)
{
	if (obj == nullptr)
		return;

	m_item.cmdId = obj->value("id").toInt();
	construct(m_item.cmdId);
}

void AppMenuItem::onHoverChanged()
{
	s_notifying = true;
	if (m_hover)
	{
		if (AppMenuPanel::g_menuPanel()->hasAddedToFav(m_item.cmdId))
		{
			m_btn->setImgId(m_isInFav ? "guiframe_catalogue_delete" : "guiframe_catalogue_added");
			m_btn->setVisible(true);
		}
		else if (AppMenuPanel::g_menuPanel()->canAddToFav())
		{
			m_btn->setImgId("guiframe_catalogue_add");
			m_btn->setVisible(true);
		}
		
		m_labelAbbr->setVisible(false);
		m_layout->addSpacerItem(m_spacer);
	}
	else
	{
		m_btn->setVisible(false);
		m_labelAbbr->setVisible(true);
		m_layout->removeItem(m_spacer);
	}

	update();
	AppMenuPanel::g_menuPanel()->onItemHoverChanged(m_item.cmdId, m_hover);
	s_notifying = false;
}

void AppMenuItem::onBtnClicked()
{
	bool add = !AppMenuPanel::g_menuPanel()->hasAddedToFav(m_item.cmdId);
	AppMenuPanel::g_menuPanel()->onItemAction(m_item.cmdId, add);
	m_btn->setImgId(add ? (m_isInFav ? "guiframe_catalogue_delete" : "guiframe_catalogue_added") :"guiframe_catalogue_add");
}
